<script setup lang="ts">
import { h } from 'vue'
import type { DataTableColumns } from 'naive-ui'
import { NButton, NPopconfirm, NSpace, NTag } from 'naive-ui'
import { PROPERTY_CATEGORIES, PROPERTIES_BY_CATEGORY, templateToProperty } from '@/constants/device-properties'
import type { PropertyTemplate } from '@/constants/device-properties'
import NovaIcon from '@/components/common/NovaIcon.vue'

defineOptions({ name: 'PropertyManagerModal' })

interface Props {
  visible: boolean
  properties: Api.DeviceType.Property[]
}

const props = withDefaults(defineProps<Props>(), {
  visible: false,
  properties: () => [],
})

interface Emits {
  (e: 'update:visible', visible: boolean): void
  (e: 'update:properties', properties: Api.DeviceType.Property[]): void
}

const emit = defineEmits<Emits>()

const localProperties = ref<Api.DeviceType.Property[]>([])
const selectedCategory = ref<string>('电力')
const searchKeyword = ref('')

watch(
  () => props.visible,
  (visible) => {
    if (visible) {
      localProperties.value = JSON.parse(JSON.stringify(props.properties || []))
    }
  },
  { immediate: true },
)

const filteredTemplates = computed(() => {
  const templates = PROPERTIES_BY_CATEGORY[selectedCategory.value] || []
  if (!searchKeyword.value)
    return templates
  const keyword = searchKeyword.value.toLowerCase()
  return templates.filter(t => t.label.toLowerCase().includes(keyword) || t.value.toLowerCase().includes(keyword))
})

function addProperty(template: PropertyTemplate) {
  // 检查是否已存在
  if (localProperties.value.some(p => p.name === template.value)) {
    window.$message.warning(`属性 ${template.label} 已存在`)
    return
  }
  localProperties.value.push(templateToProperty(template))
  window.$message.success(`已添加 ${template.label}`)
}

function removeProperty(index: number) {
  localProperties.value.splice(index, 1)
}

function handleSave() {
  emit('update:properties', localProperties.value)
  emit('update:visible', false)
  window.$message.success('属性配置已保存')
}

function closeModal() {
  emit('update:visible', false)
}

const categoryColor = (category: string): 'default' | 'primary' | 'info' | 'success' | 'warning' | 'error' => {
  const colors: Record<string, 'default' | 'primary' | 'info' | 'success' | 'warning' | 'error'> = {
    '电力': 'warning',
    '水务': 'info',
    '燃气': 'error',
    '环境': 'success',
    '状态': 'default',
    '通用': 'default',
  }
  return colors[category] || 'default'
}

const propertyColumns: DataTableColumns<Api.DeviceType.Property> = [
  {
    title: '属性名称',
    key: 'description',
    width: 150,
  },
  {
    title: '变量名',
    key: 'name',
    width: 180,
    render: (row: Api.DeviceType.Property) => {
      return h(NTag, { size: 'small', type: 'info' }, { default: () => row.name })
    },
  },
  {
    title: '类型',
    key: 'type',
    width: 80,
    align: 'center',
  },
  {
    title: '单位',
    key: 'unit',
    width: 80,
    align: 'center',
  },
  {
    title: '小数位',
    key: 'decimal',
    width: 80,
    align: 'center',
  },
  {
    title: '上报',
    key: 'reported',
    width: 80,
    align: 'center',
    render: (row: Api.DeviceType.Property) => {
      return row.reported
        ? h(NTag, { size: 'small', type: 'success' }, { default: () => '是' })
        : h(NTag, { size: 'small' }, { default: () => '否' })
    },
  },
  {
    title: '操作',
    key: 'actions',
    width: 80,
    align: 'center',
    render: (_: Api.DeviceType.Property, index: number) => {
      return h(NPopconfirm, {
        onPositiveClick: () => removeProperty(index),
      }, {
        default: () => '确认删除？',
        trigger: () => h(NButton, { size: 'small', type: 'error', quaternary: true }, { default: () => '删除' }),
      })
    },
  },
]
</script>

<template>
  <NModal
    v-model:show="props.visible"
    title="属性管理"
    preset="card"
    class="w-90vw h-85vh"
  >
    <div class="flex gap-16px" style="height: calc(85vh - 150px);">
      <!-- 左侧：标准属性库 -->
      <div class="h-full w-350px flex flex-col gap-12px border-r border-gray-200 pr-16px dark:border-gray-700">
        <div class="flex items-center justify-between">
          <span class="font-bold">标准属性库</span>
          <NTag size="small" type="primary">
            {{ filteredTemplates.length }} 个
          </NTag>
        </div>

        <!-- 分类选择 -->
        <NSpace>
          <NTag
            v-for="category in PROPERTY_CATEGORIES"
            :key="category"
            :type="selectedCategory === category ? categoryColor(category) : 'default'"
            :bordered="false"
            class="cursor-pointer"
            @click="selectedCategory = category"
          >
            {{ category }}
          </NTag>
        </NSpace>

        <!-- 搜索 -->
        <NInput
          v-model:value="searchKeyword"
          placeholder="搜索属性..."
          clearable
        >
          <template #prefix>
            <NovaIcon icon="icon-park-outline:search" />
          </template>
        </NInput>

        <!-- 属性模板列表 -->
        <div class="flex-1 min-h-0 overflow-y-auto">
          <div
            v-for="template in filteredTemplates"
            :key="template.value"
            class="mb-8px flex cursor-pointer items-start justify-between gap-8px rounded-6px border border-gray-200 p-12px transition-all hover:border-primary hover:shadow-sm dark:border-gray-700"
            @click="addProperty(template)"
          >
            <div class="flex-1">
              <div class="flex items-center gap-8px">
                <span class="font-medium">{{ template.label }}</span>
                <NTag size="tiny" :type="categoryColor(template.category)">
                  {{ template.category }}
                </NTag>
              </div>
              <div class="mt-4px text-12px text-gray-500">
                <NTag size="tiny" type="info">
                  {{ template.value }}
                </NTag>
                <span class="ml-8px">{{ template.type }}</span>
                <span v-if="template.unit" class="ml-8px">{{ template.unit }}</span>
              </div>
              <div v-if="template.description" class="mt-4px text-12px text-gray-400">
                {{ template.description }}
              </div>
            </div>
            <NovaIcon icon="icon-park-outline:add-one" :size="18" color="var(--primary-color)" />
          </div>
        </div>

        <!-- 提示 -->
        <NAlert type="info" size="small" :bordered="false">
          <template #icon>
            <NovaIcon icon="icon-park-outline:info" />
          </template>
          点击属性卡片添加到右侧列表
        </NAlert>
      </div>

      <!-- 右侧：已选属性列表 -->
      <div class="h-full flex-1 flex flex-col gap-12px">
        <div class="flex items-center justify-between flex-shrink-0">
          <span class="font-bold">已选属性</span>
          <NTag size="small" type="success">
            {{ localProperties.length }} 个
          </NTag>
        </div>

        <!-- 属性表格 -->
        <div class="flex-1 min-h-0 overflow-hidden">
        <NDataTable
          :columns="propertyColumns"
          :data="localProperties"
            :max-height="450"
          :scroll-x="800"
          size="small"
        />
        </div>

        <!-- 说明 -->
        <NAlert type="warning" size="small" :bordered="false" class="flex-shrink-0">
          <template #header>
            属性与协议的关系
          </template>
          <div class="text-13px">
            <p class="mb-4px">
              <strong>变量名（name）</strong> 是 Lua 协议返回的标识符，需要与协议中的变量名对应。
            </p>
            <p class="mb-4px">
              例如：Lua 中 <code>utils.AppendVariable(0, "voltage_a", "A相电压", "double", 220.5, "V")</code>
            </p>
            <p>
              则此处的变量名应填写 <code>voltage_a</code>，或使用标准的 <code>dev_voltage_a</code>
            </p>
          </div>
        </NAlert>
      </div>
    </div>

    <template #footer>
      <NSpace justify="end">
        <NButton @click="closeModal">
          取消
        </NButton>
        <NButton type="primary" @click="handleSave">
          保存配置
        </NButton>
      </NSpace>
    </template>
  </NModal>
</template>

<style scoped>
code {
  background-color: rgba(0, 0, 0, 0.06);
  padding: 2px 6px;
  border-radius: 3px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 12px;
}

.dark code {
  background-color: rgba(255, 255, 255, 0.1);
}
</style>

